/*
 * Copyright (c) 2012 Aleksander Zotov, Benedikt Markt, Aliaksei Babkovich
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 *  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

// TODO add to draft
/**
 * This class contains various utilities to convert and format String and Date types
 * 
 * @author Benedikt Markt
 *
 */
public class DateUtils {
	/*
	 * Supported date formats
	 */
	SimpleDateFormat germanDateA = new SimpleDateFormat("dd.MM.yy");
	SimpleDateFormat germanDateB = new SimpleDateFormat("yy-MM-dd");
	SimpleDateFormat germanDateC = new SimpleDateFormat("dd.MM.yyyy");
	SimpleDateFormat germanDateD = new SimpleDateFormat("yyyy-MM-dd");
	SimpleDateFormat englishDateA = new SimpleDateFormat("MM/dd/yy");
	SimpleDateFormat englishDateB = new SimpleDateFormat("MM/dd/yyyy");
	SimpleDateFormat germanDateTimeA = new SimpleDateFormat("dd.MM.yy, HH:mm");
	SimpleDateFormat germanDateTimeB = new SimpleDateFormat("yy-MM-dd, HH:mm");
	SimpleDateFormat germanDateTimeC = new SimpleDateFormat("dd.MM.yyyy, HH:mm");
	SimpleDateFormat germanDateTimeD = new SimpleDateFormat("yyyy-MM-dd, HH:mm");
	SimpleDateFormat englishDateTimeA = new SimpleDateFormat(
			"MM/dd/yy, hh:mm aa");
	SimpleDateFormat englishDateTimeB = new SimpleDateFormat(
			"MM/dd/yyyy, hh:mm aa");
	SimpleDateFormat catoDateTime = new SimpleDateFormat("yyyy MM dd hh mm ss");

	public DateUtils() {
		germanDateA.setLenient(false);
		germanDateB.setLenient(false);
		germanDateC.setLenient(false);
		germanDateD.setLenient(false);
		englishDateA.setLenient(false);
		englishDateB.setLenient(false);
		germanDateTimeA.setLenient(false);
		germanDateTimeB.setLenient(false);
		germanDateTimeC.setLenient(false);
		germanDateTimeD.setLenient(false);
		englishDateTimeA.setLenient(false);
		englishDateTimeB.setLenient(false);
	}

	/**
	 * Checks if the given String contains a valid date
	 * 
	 * @param date
	 *            the string to check.
	 * @return true if the String contains a valid date, otherwise false.
	 */
	public boolean isValidDate(String date) {

		@SuppressWarnings("unused")
		Date validateHelper;
		if (date.length() > 10) {
			try {
				validateHelper = germanDateTimeA.parse(date);
			} catch (ParseException e) {
				try {
					validateHelper = germanDateTimeB.parse(date);
				} catch (ParseException f) {

					try {
						validateHelper = germanDateTimeC.parse(date);
					} catch (ParseException g) {
						try {
							validateHelper = germanDateTimeD.parse(date);
						} catch (ParseException h) {
							try {
								validateHelper = englishDateTimeA.parse(date);
							} catch (ParseException i) {
								try {
									validateHelper = englishDateTimeB
											.parse(date);
								} catch (ParseException j) {
									return false;
								}
							}
						}
					}
				}
			}
		} else {
			try {
				validateHelper = germanDateA.parse(date);
			} catch (ParseException h) {

				try {
					validateHelper = germanDateB.parse(date);
				} catch (ParseException i) {

					try {
						validateHelper =germanDateC.parse(date);
					} catch (ParseException j) {
						try {
							validateHelper = germanDateD.parse(date);
						} catch (ParseException k) {
							try {
								validateHelper = englishDateA.parse(date);
							} catch (ParseException l) {
								try {
									validateHelper = englishDateB.parse(date);
								} catch (ParseException m) {
									return false;
								}
							}
						}
					}
				}
			}
		}
		return true;
	}

	/**
	 * converts a String that contains a date and/or time in German or English
	 * format to a Date type.
	 * 
	 * @param date
	 *            a string containig a date and/or time
	 * @return the date as java.util.Date type.
	 */
	public Date toDate(String date) {
		Date convDate;
		try {
			convDate = germanDateTimeA.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateTimeB.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateTimeC.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateTimeD.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = englishDateTimeA.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = englishDateTimeB.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateA.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateB.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateC.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = germanDateD.parse(date);
			return convDate;
		} catch (ParseException e) {
		}
		try {
			convDate = englishDateA.parse(date);
			return convDate;
		} catch (ParseException e) {
		}

		try {
			convDate = englishDateB.parse(date);
			return convDate;
		} catch (ParseException e) {
		}
		return new Date();
	}

	/**
	 * Converts a date to a localized string
	 * 
	 * @param date
	 *            the date to convert
	 * @return the date as a string
	 */
	public String toLocalizedString(Date date, Locale locale) {

		if (locale == Locale.GERMANY) {
			return germanDateTimeA.format(date);
		} else {
			return englishDateTimeB.format(date);
		}
	}

	public String toCatoString(Date date) {
		return catoDateTime.format(date);
	}
}
